package com.piccolo.wrapper.client.component;

import java.util.List;

import com.piccolo.wrapper.client.component.Overlay.PNodeOverlay;
import com.piccolo.wrapper.client.handler.PBasicInputEventHandler;

/**
 * @author Maria Patrickson
 * @version 1.0
 */
public class PNode 
{
	protected PNodeOverlay overlay;
	
	/**
	 * Creates a new PNode.
	 */
	public PNode() 
	{
		this.overlay = PNodeOverlay.create();
	}

	/**
	 * Creates a new PNode with the specified style and boundaries.
	 * @param fillStyle
	 * @param bounds
	 */
	public PNode(String fillStyle, PBounds bounds)
	{
		this.overlay = PNodeOverlay.create(fillStyle, bounds);
	}
	
	/**
	 * Constructs a PNode with the specified PNodeOverlay. 
	 * @param overlay
	 */
	public PNode(PNodeOverlay overlay)
	{
		this.overlay = overlay;
	}

	/**
	 * @return The JavaScript overlay for this object.
	 */
	public PNodeOverlay getOverlay()
	{
		return overlay;
	}
	
	/**
	 * @return A list of all children of this node
	 */
	public List<PNode> getChildren()
	{
		return overlay.getChildren();
	}
	
	/**
	 * Adds a new child node to this node.
	 * @param child
	 */
	public void addChild(PNode child)
	{
		overlay.addChild(child);
	}

	/**
	 * Translate this node's transform by the given amount, using the standard affine transform translate method.
	 * @param x
	 * @param y
	 */
	public void translate(double x, double y)
	{
		overlay.translate(x, y);	
	}

	/**
	 * Scale this node's transform by the given amount.
	 * @param scale
	 */
	public void scale(double scale) 
	{ 
		overlay.scale(scale);	
	}
	
	/**
	 * Set the display scale for this node.
	 * @param displayScale
	 */
	public void setDisplayScale(double displayScale)
	{
		overlay.setDisplayScale(displayScale);
	}
	
	/**
	 * Returns the display scale for this node.
	 * @return
	 */
	public double getDisplayScale() 
	{
		return overlay.getDisplayScale();
	}
	
	/**
	 * Adds a click listener to this node.
	 * @param handler
	 */
	public void addClickListener(PBasicInputEventHandler handler) 
	{
		overlay.addClickListener(handler);
	}

	/**
	 * Adds a mouse over listener to this node
	 * @param handler
	 */
	public void addMouseOverListener(PBasicInputEventHandler handler) 
	{
		overlay.addMouseOverListener(handler);
	}
	
	/**
	 * Adds a mouse out listener to this node
	 * @param handler
	 */
	public void addMouseOutListener(PBasicInputEventHandler handler) 
	{
		overlay.addMouseOutListener(handler);
	}

	public PTransform getGlobalTransform() 
	{
		return overlay.getGlobalTransform();
	}

	public PBounds getGlobalFullBounds() 
	{
		return overlay.getGlobalFullBounds();
	}
	
	public void paintAfterChildren(PCanvas canvas)
	{
		overlay.paintAfterChildren(canvas);
	}

	/**
	 * @return The bounds for this object
	 */
	public PBounds getBounds() 
	{
		return overlay.getBounds();
	}
	
	/**
	 * Set the bounds for this object to the specified bounds. 
	 * @param bounds
	 */
	public void setBounds(PBounds bounds) 
	{
		overlay.setBounds(bounds);
	}
	
	/**
	 * Set the transform of this node
	 * @param transformation
	 */
	public void setTransform(PTransform transformation) 
	{
		overlay.setTransform(transformation);
	}

	/**
	 * Rotate this node's transform by the given amount.
	 * @param scale
	 */
	public void rotate(double theta) 
	{
		overlay.rotate(theta);
	}

	/**
	 * @return The root of this object
	 */
	public PRoot getRoot()
	{
		return overlay.getRoot();
	}
	
    public void removeChild(PNode child) 
    {
    	overlay.removeChild(child);
    }

    public void animateToTransform(PTransform transform, double duration) 
    {
    	overlay.animateToTransform(transform, duration);
    }

    public PBounds getFullBounds() 
    {
    	return overlay.getFullBounds();
    }

    public void invalidateBounds() 
    { 
    	overlay.invalidateBounds();
    }

    public PTransform localToParent(PTransform target) 
    {
    	return overlay.localToParent(target);
    }
    
    public PPoint localToParent(PPoint target) 
    { 
    	return overlay.localToParent(target);
    }
    
    public PBounds localToParent(PBounds target) 
    {     	
    	return overlay.localToParent(target);
}
    
    public PTransform parentToLocal(PTransform target) 
    {
    	return overlay.parentToLocal(target);
    }

    public PPoint parentToLocal(PPoint target) 
    {
    	return overlay.parentToLocal(target);
    }

    public PBounds parentToLocal(PBounds target) 
    {
    	return overlay.parentToLocal(target);
    }

    public void moveToFront()
    {
    	overlay.moveToFront();
    }
    
    public void moveToBack() 
    {
    	overlay.moveToBack();
    }
}
